static struct proc_dir_entry *dom0_cmd_intf;
static struct proc_dir_entry *dom_list_intf;
- unsigned long direct_mmap(unsigned long, unsigned long, pgprot_t, int);
-unsigned long direct_mmap(unsigned long, unsigned long, pgprot_t, int, int);
++int direct_unmap(unsigned long, unsigned long);
int direct_unmap(struct mm_struct *, unsigned long, unsigned long);
static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff_t * off)
}
}
- if ( direct_unmap(current->mm, mem_data.vaddr,
+ static ssize_t dom_mem_write(struct file * file, const char * buff,
+ size_t size , loff_t * off)
+ {
+ dom_mem_t mem_data;
+
+ printk("dom_mem_write called: Shouldn't happen.\n");
+
+ copy_from_user(&mem_data, (dom_mem_t *)buff, sizeof(dom_mem_t));
+
++ if ( direct_unmap(mem_data.vaddr,
+ mem_data.tot_pages << PAGE_SHIFT) == 0 ) {
+ return sizeof(sizeof(dom_mem_t));
+ } else {
+ return -1;
+ }
+ }
+
+ static ssize_t dom_mem_read(struct file * file, char * buff, size_t size, loff_t * off)
+ {
+ unsigned long addr;
+ pgprot_t prot;
+
+ proc_memdata_t * mem_data = (proc_memdata_t *)((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
+
+ prot = PAGE_SHARED;
+
+ /* remap the range using xen specific routines */
+
+ printk("Calling direct_mmap with pfn %x, tot pages %x.\n",
+ mem_data->pfn, mem_data->tot_pages);
+
+ addr = direct_mmap(mem_data->pfn << PAGE_SHIFT, mem_data->tot_pages << PAGE_SHIFT, prot, MAP_DISCONT, mem_data->tot_pages);
+
+ copy_to_user((unsigned long *)buff, &addr, sizeof(addr));
+
+ return sizeof(addr);
+ }
+
+ struct file_operations dom_mem_ops = {
+ read: dom_mem_read,
+ write: dom_mem_write,
+ };
+
+ static int dom_map_mem(unsigned int dom, unsigned long pfn, int tot_pages)
+ {
+ int ret = -ENOENT;
+ struct proc_dir_entry * pd = xeno_base->subdir;
+ struct proc_dir_entry * file;
+ proc_memdata_t * memdata;
+
+ while(pd != NULL){
+
+ if((pd->mode & S_IFDIR) && ((dom_procdata_t *)pd->data)->domain == dom){
+
+ /* check if there is already an entry for mem and if so
+ * remove it.
+ */
+ /* XXX does this not leak the memdata? */
+ remove_proc_entry("mem", pd);
+
+ /* create new entry with parameters describing what to do
+ * when it is mmaped.
+ */
+ file = create_proc_entry("mem", 0600, pd);
+ if(file != NULL)
+ {
+ file->owner = THIS_MODULE;
+ file->nlink = 1;
+ file->proc_fops = &dom_mem_ops;
+
+ memdata = (proc_memdata_t *)kmalloc(sizeof(proc_memdata_t), GFP_KERNEL);
+ memdata->pfn = pfn;
+ memdata->tot_pages = tot_pages;
+ file->data = memdata;
+
+ ret = 0;
+ break;
+ }
+
+ ret = -EAGAIN;
+ break;
+ }
+ pd = pd->next;
+ }
+
+ return ret;
+ }
+
+ /* function used to retrieve data associated with new domain */
+ static ssize_t dom_data_read(struct file * file, char * buff, size_t size, loff_t * off)
+ {
+ dom0_newdomain_t * dom_data = (dom0_newdomain_t *)
+ ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
+
+ copy_to_user((dom0_newdomain_t *)buff, dom_data, sizeof(dom0_newdomain_t));
+
+ remove_proc_entry("new_dom_data", xeno_base);
+
+ kfree(dom_data);
+
+ return sizeof(dom0_newdomain_t);
+ }
+
+ struct file_operations newdom_data_fops = {
+ read: dom_data_read,
+ };
+
static int dom0_cmd_write(struct file *file, const char *buffer, size_t size,
loff_t *off)
{